package com.teamin.web.socket;

import com.mysql.cj.core.util.StringUtils;
import com.teamin.service.JwtService;
import com.teamin.web.exception.GlobalErrorInfoException;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
import org.springframework.messaging.handler.invocation.HandlerMethodReturnValueHandler;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptorAdapter;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;

import java.security.Principal;
import java.util.List;
import java.util.Map;

/**
 * 通过EnableWebSocketMessageBroker 开启使用STOMP协议来传输基于代理(message broker)的消息,此时浏览器支持使用@MessageMapping 就像支持@RequestMapping一样。
 * Created by qfu on 2017/10/23.
 */

@Configuration
@EnableWebSocketMessageBroker
public class LiteWebStompConfig implements WebSocketMessageBrokerConfigurer {

    @Autowired
    private JwtService jwtService;
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //portfolio-stomp就是websocket的端点，客户端需要注册这个端点进行链接
        registry.addEndpoint("/stomp").setAllowedOrigins("*") ;
        //.withSockJS();
        ;
    }

    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration webSocketTransportRegistration) {

    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration channelRegistration) {
        channelRegistration.setInterceptors(new ChannelInterceptorAdapter() {

            @Override
            public Message<?> preSend(Message<?> message, MessageChannel channel) {

                StompHeaderAccessor accessor =
                        MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

                if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                    String userId = getUserId(message);
                    logger.info("-------websocket user_id="+userId);
                    if(StringUtils.isNullOrEmpty(userId)) {
                        return null ;
                    }

                    Principal user = new Principal() {
                        @Override
                        public String getName() {
                            return userId ;
                        }
                    } ;
                    accessor.setUser(user);

                    if(user != null) {
                        SessionManager.addSession(user.getName(),accessor.getSessionId());
                    }

                }else if (StompCommand.DISCONNECT.equals(accessor.getCommand())) {
                    if(accessor.getUser() != null) {
                        SessionManager.deleteSessionUser(accessor.getUser().getName(),accessor.getSessionId());
                    }
                }

                return super.preSend(message, channel);
            }

            @Override
            public Message<?> postReceive(Message<?> message, MessageChannel channel) {
                System.out.println(message.toString()+"     "+message.getPayload().toString());

                return super.postReceive(message, channel);
            }

            @Override
            public boolean preReceive(MessageChannel channel) {
                return super.preReceive(channel);
            }
        });
    }

    public String getUserId(Message<?> message) {
        LinkedMultiValueMap o = (LinkedMultiValueMap) message.getHeaders().get("nativeHeaders");
        Claims claims = null;
        try {
            claims = jwtService.readToken(""+(o.get("Authorization").get(0)));
            // token中携带的登陆信息转换成map类型
            @SuppressWarnings("unchecked")
            Map<String, String> loginInfo = (Map<String, String>) claims.get("loginInfo");
            return String.valueOf(loginInfo.get("userId")) ;
        } catch (GlobalErrorInfoException e) {
            e.printStackTrace();
        }
        return null ;
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration channelRegistration) {

    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> list) {

    }

    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> list) {

    }

    @Override
    public boolean configureMessageConverters(List<MessageConverter> list) {
        return false;
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        //config.setApplicationDestinationPrefixes("/subscript");
        config.enableSimpleBroker("/circle","/task","/notification");////设置服务器广播消息的基础路径
        config.setApplicationDestinationPrefixes("/app");  //户端给服务端发消息的地址的前缀
    }

}
